#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <strings.h>
#include <unistd.h>
#include <memory>
#include "Log.hpp"
enum
{
    SOCK_ERR = 1,
    BIND_ERR
};
class UDPServer
{
public:
    UDPServer(uint16_t port) : _sockfd(-1), _port(port)
    {
    }
    void InitServe()
    {
        static LogType log;
        _sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        if (_sockfd < 0)
        {
            std::cerr << "create socket error!" << std::endl;
            exit(SOCK_ERR);
        }
        std::cout << "------------" <<std::endl;
        log(DEBUG,__LINE__,__FILE__,"%s","create socket success!");
        struct sockaddr_in local;
        bzero(&local, sizeof(local));
        local.sin_addr.s_addr = INADDR_ANY;
        local.sin_family = AF_INET;
        local.sin_port = htons(_port);
        int n = bind(_sockfd, reinterpret_cast<const sockaddr *>(&local), sizeof(local));
        if (n < 0)
        {
            std::cerr << "bind socket error!" << std::endl;
            exit(BIND_ERR);
        }
        log(DEBUG,__LINE__,__FILE__,"%s","bind socket success!");
        int ret = listen(_sockfd,1);
    }
    void Start()
    {
        _isrunning = true;
        struct sockaddr addr;
        while (true)
        {
            socklen_t size = sizeof(addr);
            char buffer[1024];
            ssize_t n = recvfrom(_sockfd, buffer, 1024, MSG_WAITALL, &addr, &size);
            if (n > 0)
                std::cout << "receipt message:" << buffer << std::endl;
            sleep(1);
        }
        _isrunning = false;
    }

private:
    int _sockfd;
    uint16_t _port;
    bool _isrunning;
};
void Usage(std::string use)
{
    std::cout << "Usage:\n\r " <<" "<< use << " " << "local_port" << std::endl;
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        Usage(argv[0]);
        exit(-1);
    }
    uint16_t port = static_cast<uint16_t>(std::stoi(argv[1]));

    UDPServer udp(port);

    udp.Start();
    return 0;
}